/**
 * 公共工具
 */
import Taro from '@tarojs/taro'
import Store from '../store/index'

// 等待程序初始化
const waitAppInit = async () => {
  if (getStoreValue(Store).isInit) {
    Taro.showLoading({
      title: '程序加载中'
    })
    while (true) {
      await sleep(200)
      if (getStoreValue(Store).isInit) {
        Taro.showLoading({
          title: '程序加载中'
        })
        break
      } 
      if (getStoreValue(Store).initFail) {
        Taro.hideLoading()
        return false // 初始化失败后，直接停止运行
      }
    }
  }
  return true
}
// 跳转路由（url是绝对路径 /pages/home/index
const redirectToPage = (url: string, isReLaunch?: boolean) => {
  const pages: Array<object> = Taro.getCurrentPages()
  // 容错检查
  if (url.indexOf('/') !== 0) {
    url = '/' + url
  }
  let index: number
  // 多端兼容处理
  switch (process.env.TARO_ENV) {
    case 'h5':
      index = pages.findIndex(item => (item['$router'].path) === url)
      break
    case 'weapp':
      index = pages.findIndex(item => ('/' + item['route']) === url)
      break
    case 'swan':
      index = pages.findIndex(item => ('/' + item['route']) === url)
      break
    case 'tt':
      index = pages.findIndex(item => ('/' + item['_route_']) === url)
      break
    case 'alipay':
      console.log(pages[0])
      index = pages.findIndex(item => ('/' + item['route']) === url)
      break
    default:
      console.log(pages)
      index = pages.findIndex(item => ('/' + item['route']) === url)
  }
  // 关闭页面栈，重新打开
  if (isReLaunch) {
    Taro.reLaunch({ url })
    .catch(ex => {
      if (ex.errMsg && ex.errMsg.indexOf("is not found") > 0) {
        goToErrorPage(404)
      } else {
        throw ex
      }
    })
  } else if (index >= 0) {
    const delta: number = pages.length - 1 - index
    switch (delta) {
      case 0:
        // 当前页，不跳
        return
      case 1:
        Taro.navigateBack({ delta })
    }
  // 能跳tabbar的，跳tabbar页面
  } else if (isTabPage(url)){
    Taro.switchTab({
      url,
      fail() {
        otherToPage(url, pages.length) // 尝试用另一种方法打开
      }
    })
  // 尝试用另一种方法打开
  } else {
    otherToPage(url, pages.length)
  }
}
// 判断是否为tabbar页面
const isTabPage = (url: string) => {
  let pages = getStoreValue(Store).tabList
  if (!pages) pages = []  // 修正没数据的情况
  url = url.substring(1)
  // let res: boolean = pages.indexOf(url) >= 0
  let res: boolean = false
  pages.forEach(item => {
    if (item.pagePath === url) res = true
  })
  return res
}
// 另一种跳转路由的方式
const otherToPage = (url: string, curPagesLength: number) => {
  if (curPagesLength < 8) {
    Taro.navigateTo({ url })
    .catch(ex => {
      if (ex.errMsg && ex.errMsg.indexOf("is not found") > 0) {
        goToErrorPage(404)
      } else {
        throw ex
      }
    })
  // 超过了,开启新的页队栈
  } else {
    Taro.reLaunch({ url })
    .catch(ex => {
      if (ex.errMsg && ex.errMsg.indexOf("is not found") > 0) {
        goToErrorPage(404)
      } else {
        throw ex
      }
    })
  }
}
// 跳转异常页
const goToErrorPage = (bizcode: number, msg: any = null) => {
  const currentPage = getCurrentPageUrl()
  if (currentPage === '/pages/error/index') {
    throw new Error('报错页死循环')
  }  
  const returnUrl: string = escape(getCurrentPageUrlWithArgs()) // 解码后 获取返回的路由及其参数
  let url = `/pages/error/index?type=${bizcode}&returnUrl=${returnUrl}`
  if (msg) url += `&msg=${msg}`
  Taro.redirectTo({ url })
}
// 获取当前页面
const getCurrentPageUrl = () => {
  const pages: Array<object>  = Taro.getCurrentPages()
  const currentPages: object = pages[pages.length - 1]
  let url: string = ''
  // 多端兼容处理
  switch (process.env.TARO_ENV) {
    case 'h5':
      url = currentPages['$router'].path
      break
    case 'weapp':
      url = '/' + currentPages['route']
      break
    case 'alipay':
      url = '/' + currentPages['route']
      break
    case 'tt':
      url = '/' + currentPages['_route_']
      break
    case 'swan':
      url = '/' + currentPages['route']
      break
    default:
      console.log(currentPages)
      url = '/' + currentPages['route']
  }
  return url
}
// 获取当前页面参数
const getCurrentPageArgs = () => {
  const pages: Array<object> = Taro.getCurrentPages()
  const currentPages: object = pages[pages.length - 1]
  let options: object = {}
  // 多端兼容处理
  switch (process.env.TARO_ENV) {
    case 'h5':
      options = currentPages['$router'].params
      break
    case 'weapp':
      options = currentPages['options']
      break
    case 'alipay':
      options = currentPages['$component'].$router.params
      break
    case 'tt':
      options = currentPages['options']
      break
    case 'swan':
      options = currentPages['options']
      break
    default:
      console.log(currentPages)
      options = currentPages['options']
  }
  return options
}
// 获取当前路由，带参数
const getCurrentPageUrlWithArgs = () => {
  let url: string = getCurrentPageUrl()
  let options: object = getCurrentPageArgs()
  let urlWithArgs: string = ''
  for (let key in options) {
    let value = options[key]
    urlWithArgs += `${key}=${value}&`
  }
  if (urlWithArgs) {
    urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1)
    url = `${url}?${urlWithArgs}`
  }
  return url
}
// 金额格式化(分->元 保留2位小数 并每隔3位用逗号分开 1,234.56
const abs = (s: any, type?: number) => {
  if (/[^0-9\.]/.test(s)) return '0.00'
  if (s === null || s === 'null' || s === '') return '0.00'
  s = s.toString().replace(/^(\d*)$/, '$1.')
  s = (s + '00').replace(/(\d*\.\d\d)\d*/, '$1')
  s = s.replace('.', ',')
  let re = /(\d)(\d{3},)/
  while (re.test(s)) s = s.replace(re, '$1,$2')
  s = s.replace(/,(\d\d)$/, '.$1')
  if (type === 0) {
    let a = s.split('.')
    if (a[1] === '00') s = a[0]
  }
  return s
}
// 获取仓库的值
const getStoreValue = (store: any, isContext?: boolean) => {
  if (isContext) {
    // 多端兼容处理
    switch (process.env.TARO_ENV) {
      case 'h5':
        return store['_defaultValue']
      default:
        return store['context']._defaultValue
    }
  } else {    
    return store
  }
}
// 睡眠
const sleep = (s: number) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(s)
    })
  })
}
// 等待异步结果
const awtAsyncFunc = async asyncFunc => {
  return await asyncFunc.catch(ex => {
    throw ex
  })
}
// 格式化时间戳为日期
const formatTime = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()
  const formatNumber = (n: number | string) : string => {
    n = n.toString()
    return n[1] ? n : '0' + n
  }
  return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}

export {
  redirectToPage,
  isTabPage,
  otherToPage,
  goToErrorPage,
  getCurrentPageUrl,
  getCurrentPageArgs,
  getCurrentPageUrlWithArgs,
  abs,
  getStoreValue,
  sleep,
  waitAppInit,
  awtAsyncFunc,
  formatTime,
}
